use crate::util::get_vite_config_path;
use common::model::{Alias, ProjectConfig};
use common::model::{CodeModule, LibImport};
use common::traits::{
    CommonModuleTrait, ObjectLitTrait, ViteConfigTrait, ViteConfigUpdatedModuleTrait,
};
use std::fs;
use std::path::Path;

pub fn apply_alias(
    project_config: &ProjectConfig,
    project_dir: &Path,
) -> Result<(), Box<dyn std::error::Error>> {
    if let Some(aliases) = &project_config.aliases {
        let vite_config_path = &get_vite_config_path(project_dir);
        let mut code_module = CodeModule::new(&fs::read_to_string(vite_config_path)?)?;
        code_module.init_resolve_node()?;
        code_module.init_alias_node()?;
        code_module.init_import(&LibImport {
            lib_name: "path".to_string(),
            element_name: "resolve".to_string(),
            is_default: false,
            command: None,
        })?;

        for alias in aliases {
            add_alias(&mut code_module, alias)?;
        }

        fs::write(vite_config_path, code_module.get_source())?;
    }

    Ok(())
}

fn add_alias(
    code_module: &mut CodeModule,
    alias: &Alias,
) -> Result<(), Box<dyn std::error::Error>> {
    if let Some(alias_object) = code_module.update_module()?.try_get_alias_node() {
        if !alias_object.has_key(&alias.name) {
            code_module.insert_alias(alias)?;
        } else {
            println!("alias:{} 已存在，操作被跳过", &alias.name);
        }
    }
    Ok(())
}
